package poc.spring.model;

public class CartesianRectangle2D {
	private double west;
	private double north;
	private double east;
	private double south;
	
	public CartesianRectangle2D(double west, double north, double east, double south) {
		super();
		this.west = west;
		this.north = north;
		this.east = east;
		this.south = south;
	}
	
	/**
	 * Tests whether two rectangles intersect. The edges of the rectangles must be 
	 * parallel to the Cartesian axes. If the rectangles share an edge or point 
	 * then they will intersect.
	 * @param rect The rectangle to test against
	 * @return True if the rectangles intersect, else false.
	 */
	public boolean intersects(CartesianRectangle2D rect) {
		// Test all four points of this rectangle to see if the argument contains a point.
		// If no luck, then the argument may be partially or totally enclosed within this
		// rectangle. So, check all four points of the argument to see if this rectangle 
		// contains a point. If still no luck then the rectangles do not intersect.
		
		return this.containsPoint(rect.west, rect.north) ||
		       this.containsPoint(rect.east, rect.north) ||
		       this.containsPoint(rect.west, rect.south) ||
		       this.containsPoint(rect.east, rect.south) ||
		       rect.containsPoint(this.west, this.north) ||
		       rect.containsPoint(this.east, this.north) ||
		       rect.containsPoint(this.west, this.south) ||
		       rect.containsPoint(this.east, this.south);
	}
	
	public boolean intersects(double west, double north, double east, double south) {
		return intersects(new CartesianRectangle2D(west, north, east, south));
	}
	
	public boolean containsPoint(double x, double y) {
		return (x >= west && x <= east && y <= north && y >= south);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(east);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(north);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(south);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(west);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		CartesianRectangle2D other = (CartesianRectangle2D) obj;
		if (Double.doubleToLongBits(east) != Double.doubleToLongBits(other.east))
			return false;
		if (Double.doubleToLongBits(north) != Double.doubleToLongBits(other.north))
			return false;
		if (Double.doubleToLongBits(south) != Double.doubleToLongBits(other.south))
			return false;
		if (Double.doubleToLongBits(west) != Double.doubleToLongBits(other.west))
			return false;
		return true;
	}
}
